In [2]:
import numpy as np
from BZI.symmetry import make_ptvecs, make_rptvecs
from BZI.sampling import sphere_pts
In [5]:
# These lattice constants were calculated in Mathematica and
# are such that the volumes are the same.
a_fcc = 1.
a_bcc = 0.793701
a_sc = 0.629961
fcc_consts = [a_fcc]*3
bcc_consts = [a_bcc]*3
sc_consts = [a_sc]*3
lat_angles = [np.pi/2]*3
fcc_lat_vecs = make_ptvecs("face", fcc_consts, lat_angles)
fcc_rlat_vecs = make_rptvecs(fcc_lat_vecs)
bcc_lat_vecs = make_ptvecs("body", bcc_consts, lat_angles)
bcc_rlat_vecs = make_rptvecs(bcc_lat_vecs)
sc_lat_vecs = make_ptvecs("prim", sc_consts, lat_angles)
sc_rlat_vecs = make_rptvecs(sc_lat_vecs)
Verify the volumes are the same.
In [6]:
vol_fcc = np.linalg.det(fcc_rlat_vecs)
vol_bcc = np.linalg.det(bcc_rlat_vecs)
vol_sc = np.linalg.det(sc_rlat_vecs)
print("Lattice Vectors","\nfcc:\n", fcc_rlat_vecs, "\nbcc:\n", bcc_rlat_vecs, "\nsc:\n", sc_rlat_vecs)
print("Volumes","\nfcc: ", vol_fcc, "\nbcc: ", vol_bcc, "\nsc: ", vol_sc)
Let's see what the volumes are in real space.
In [8]:
realvol_fcc = np.linalg.det(fcc_lat_vecs)
realvol_bcc = np.linalg.det(bcc_lat_vecs)
realvol_sc = np.linalg.det(sc_lat_vecs)
print("Reciprical Lattice Vectors","\nfcc:\n", fcc_lat_vecs, "\nbcc:\n", bcc_lat_vecs, "\nsc:\n", sc_lat_vecs)
print("Reciprical Space Volumes","\nfcc: ", realvol_fcc, "\nbcc: ", realvol_bcc, "\nsc: ", realvol_sc)
Apparently the volume of the supercell in real space is the same for all three. Next let's check the length of the vectors in real space.
In [9]:
fcc_rmin = np.linalg.norm(fcc_lat_vecs[:,0])
bcc_rmin = np.linalg.norm(bcc_lat_vecs[:,0])
sc_rmin = np.linalg.norm(sc_lat_vecs[:,0])
print("Cutoffs", "\nfcc: ", fcc_rmin, "\nbcc: ", bcc_rmin, "\nsc: ", sc_rmin)
Face-centered cubic has the longest length cutoff or includes the most frequencies.
In [10]:
print("fcc/bcc: ", fcc_rmin/bcc_rmin*100 - 100)
print("fcc/sc: ", fcc_rmin/sc_rmin*100 - 100)
print("bcc/sc: ", bcc_rmin/sc_rmin*100 - 100)
In [11]:
from BZI.sampling import sphere_pts
from BZI.plots import PlotSphereMesh
In [12]:
fourier_sc = sphere_pts(sc_lat_vecs, sc_rmin, [0,0,0])
fourier_bcc = sphere_pts(bcc_lat_vecs, bcc_rmin, [0,0,0])
fourier_fcc = sphere_pts(fcc_lat_vecs, fcc_rmin, [0,0,0])
print("Number of Fourier terms sc: ", len(fourier_sc))
print("Number of Fourier terms bcc: ", len(fourier_bcc))
print("Number of Fourier terms fcc: ", len(fourier_fcc))
An fcc grid would have the most Fourier terms for a set volume.
Let's calculate the average distance of these points. I think it would be more important to have more of the closer terms.
In [13]:
sc_average_length = np.sum([np.linalg.norm(pt) for pt in fourier_sc])/len(fourier_sc)
fcc_average_length = np.sum([np.linalg.norm(pt) for pt in fourier_fcc])/len(fourier_fcc)
bcc_average_length = np.sum([np.linalg.norm(pt) for pt in fourier_bcc])/len(fourier_bcc)
print("sc ", sc_average_length)
print("fcc ", fcc_average_length)
print("bcc ", bcc_average_length)